#include <stdlib.h>
#include <string.h>

#ifdef WINVER
#include <windows.h>
#include "sound.h"
#endif

#include "calc.h"
#include "state.h"
#include "var.h"
#include "link.h"
#include "sendfiles.h"




static int SlotSave =-1;

typedef struct SENDFILES {
	char* FileNames;
	int ram;
//	HANDLE hdlSend;
} SENDFILES_t;


int SizeofFileList(char* FileNames) {
	int i;
	if (FileNames == NULL) return 0;
	for(i = 0; FileNames[i]!=0 || FileNames[i+1]!=0; i++);
	return i+2;
}

char* AppendName(char* FileNames, char* fn) {
	int length;
	char* pnt;
	int i;
	length = strlen(fn);
	if (FileNames == NULL) {
		FileNames = malloc(length+2);
		memset(FileNames,0,length+2);
		pnt = FileNames;
	} else {
		for(i = 0; FileNames[i]!=0 || FileNames[i+1]!=0; i++);
		i++;
		FileNames = realloc(FileNames,i+length+2);
		pnt = FileNames+i;
		memset(pnt,0,length+2);
	}
	strcpy(pnt,fn);
	return FileNames;
}
	

void SendFile( char* FileName , int ram ) {
	TIFILE_t *var = importvar(FileName);
	LINK_ERR result;
	if (var != NULL) {
		switch(var->type) {
			case BACKUP_TYPE:
			case VAR_TYPE:
			case FLASH_TYPE:
				result = link_send_var(&calcs[SlotSave].cpu, var, ram);
				#ifdef WINVER
				switch (result) {
				case LERR_MEM:
					switch (ram) {
					case SEND_RAM:
						MessageBox(NULL, "Not enough free RAM on calculator","Error",MB_OK);
						break;
					case SEND_ARC:
						MessageBox(NULL, "Not enough free Archive on calculator","Error",MB_OK);
						break;
					default:
						MessageBox(NULL, "Not enough free memory on calculator","Error",MB_OK);
						break;
					}
					break;
				case LERR_TIMEOUT:
					MessageBox(NULL, "Link timed out","Error",MB_OK);
					break;
				case LERR_FORCELOAD:
					MessageBox(NULL, "Error force loading an application", "Error", MB_OK);
					break;
				case LERR_CHKSUM:
					MessageBox(NULL, "Link checksum was not correct", "Error", MB_OK);
					break;
				case LERR_MODEL:
					MessageBox(NULL, "Calculator model not correct for this type of file", "Error", MB_OK);
					break;
				case LERR_NOTINIT:
					MessageBox(NULL, "Virtual link was not initialized", "Error", MB_OK);
					break;
				case LERR_LINK:
					MessageBox(NULL, "Virtual link error", "Error", MB_OK);
					break;
				case LERR_FILE:
					MessageBox(NULL, "The file was unable to be sent because it is corrupt", "Error", MB_OK);
					break;
				}
				
				#endif
				break;
			case ROM_TYPE:
			case SAV_TYPE:
				FreeTiFile(var);
				var = NULL;
				rom_load(SlotSave,FileName);
				break;
			case LABEL_TYPE:
			{
				strcpy(calcs[SlotSave].labelfn,FileName);
				state_build_applist(&calcs[SlotSave].cpu, &calcs[gslot].applist);
				printf("loading label file for slot %d: %s\n", SlotSave, FileName);
				//VoidLabels(SlotSave); BFR EDIT
				int i;
				for(i = 0; i < calcs[SlotSave].applist.count; i++) {
					//labels_app_load(SlotSave,i,calcs[SlotSave].labelfn); BFR EDIT
				}
				break;
			}
			default:
				#ifdef WINVER
				MessageBox(NULL, "The file was an invalid or unspecified type","Error",MB_OK);
				#endif
				break;
		}
	if (var) FreeTiFile(var);
	} else {
		#ifdef WINVER
		MessageBox(NULL, "Invalid file format","Error",MB_OK);
		#endif
	}
}


void SendFiles( char* FileNames , int ram ) {
	int i;
	int modelsave;
	unsigned char* fn = FileNames;
	calcs[SlotSave].send = TRUE;
	calcs[SlotSave].running = FALSE;
	calcs[SlotSave].CurrentFile = 0;
	calcs[SlotSave].FileCnt = 0;
	i=0;
	while(FileNames[i]!=0) {
		for(;FileNames[i]!=0;i++);
		i++;
		calcs[SlotSave].FileCnt++;
	}
	while (fn[0]!=0) {
		modelsave = calcs[SlotSave].model;
		calcs[SlotSave].CurrentFile++;
		SendFile(fn,ram);
		for(;fn[0]!=0;fn++);
		fn++;
	}
	//if (calcs[SlotSave].model == TI_82 && modelsave == calcs[SlotSave].model) end82send(SlotSave);
	calcs[SlotSave].running = TRUE;
	free(FileNames);
	calcs[SlotSave].send = FALSE;
}

#ifdef WINVER
DWORD WINAPI ThreadSendStart( LPVOID lpParam ) {
	SENDFILES_t* sf = lpParam;
	int save = 0;
	
	if (calcs[SlotSave].audio->enabled) {
		save = 1;
		pausesound();
	}
	
	SendFiles(sf->FileNames,sf->ram);
	if (save==1) playsound();
	free(sf);	
	SlotSave = -1;
	
    return 0; 
} 


void ThreadSend( char* FileNames , int ram ) {
	static HANDLE hdlSend = NULL;
	SENDFILES_t* sf;

	if (FileNames == NULL) return;

	if (SlotSave == -1) {
		SlotSave = gslot;
	} else {
		MessageBox(NULL, "Currently sending files please wait...","Error",MB_OK);
		return;
	}
	
	if (calcs[SlotSave].send == TRUE)  {
		MessageBox(NULL, "Currently sending files please wait...","Error",MB_OK);
		return;
	}

	if (hdlSend != NULL) {
		CloseHandle(hdlSend);
		hdlSend = NULL;
	}

	sf =  malloc(sizeof(SENDFILES_t));
	if (sf != NULL) {
		sf->FileNames	= FileNames;
		sf->ram			= ram;
	}
//	sf->hdlSend		= NULL;

    hdlSend = CreateThread(NULL,0,ThreadSendStart, sf, 0, NULL);  

    if ( hdlSend  == NULL) {
		SlotSave = -1;
		free(sf);
		free(FileNames);
		MessageBox(NULL, "Could not create thread to send","Error",MB_OK);
		return;
	}
	return;
}
#endif

void NoThreadSend(const char* FileNames, int ram) {
	if (SlotSave == -1) {
		SlotSave = gslot;
	} else {
		// error;
	}
	
	SendFiles((char*) FileNames, ram);
}


	
	
	
